package com.uduemc.biso.node.module.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.node.core.entities.SPage;
import com.uduemc.biso.node.core.entities.SSystem;
import com.uduemc.biso.node.module.common.service.*;
import com.uduemc.biso.node.module.mapper.SSystemMapper;
import com.uduemc.biso.node.module.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

@Service
public class SSystemServiceImpl implements SSystemService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private SSystemMapper sSystemMapper;

    @Resource
    private SCategoriesService sCategoriesServiceImpl;

    @Resource
    private CArticleService cArticleServiceImpl;

    @Resource
    private SDownloadAttrService sDownloadAttrServiceImpl;

    @Resource
    private CDownloadService cDownloadServiceImpl;

    @Resource
    private CProductService cProductServiceImpl;

    @Resource
    private CFaqService cFaqServiceImpl;

    @Resource
    private SComponentQuoteSystemService sComponentQuoteSystemServiceImpl;

    @Resource
    private SSeoItemService sSeoItemServiceImpl;

    @Resource
    private SSeoCategoryService sSeoCategoryServiceImpl;

    @Resource
    private SPageService sPageServiceImpl;

    @Resource
    private SSystemItemCustomLinkService sSystemItemCustomLinkServiceImpl;

    @Resource
    private SInformationTitleService sInformationTitleServiceImpl;

    @Resource
    private SPdtableTitleService sPdtableTitleServiceImpl;

    @Autowired
    private CInformationService cInformationServiceImpl;

    @Autowired
    private CPdtableService cPdtableServiceImpl;

    @Override
    public SSystem insertAndUpdateCreateAt(SSystem sSystem) {
        sSystemMapper.insert(sSystem);
        SSystem findOne = findOne(sSystem.getId());
        Date createAt = sSystem.getCreateAt();
        if (createAt != null) {
            sSystemMapper.updateCreateAt(findOne.getId(), createAt, SSystem.class);
        }
        return findOne;
    }

    @Override
    @Transactional
    public SSystem insertSystem(SSystem sSystem) {
        String errorMessage;
        int insertSelective = sSystemMapper.insertSelective(sSystem);
        if (insertSelective < 1) {
            errorMessage = "创建系统失败 sSystem:" + sSystem.toString();
            logger.error(errorMessage);
            throw new RuntimeException(errorMessage);
        }

        // 如果创建的是下载系统则自动创建三个属性
        if (sSystem.getSystemTypeId().longValue() == 5L) {
            boolean initSystemData = sDownloadAttrServiceImpl.initSystemData(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId());
            if (!initSystemData) {
                errorMessage = "初始化下载系统数据失败 sSystem:" + sSystem.toString();
                logger.error(errorMessage);
                throw new RuntimeException(errorMessage);
            }
        }

        // 如果创建的是信息系统，则自动创建三个字段
        if (sSystem.getSystemTypeId().longValue() == 7L) {
            boolean initSystemData = sInformationTitleServiceImpl.initSystemData(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId());
            if (!initSystemData) {
                errorMessage = "初始化信息系统数据失败 sSystem:" + sSystem.toString();
                logger.error(errorMessage);
                throw new RuntimeException(errorMessage);
            }
        }

        // 如果创建的是产品表格系统，则自动创建四个字段
        if (sSystem.getSystemTypeId().longValue() == 8L) {
            boolean initSystemData = sPdtableTitleServiceImpl.initSystemData(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId());
            if (!initSystemData) {
                errorMessage = "初始化产品表格系统数据失败 sSystem:" + sSystem.toString();
                logger.error(errorMessage);
                throw new RuntimeException(errorMessage);
            }
        }

        return findOne(sSystem.getId());
    }

    @Override
    public SSystem insert(SSystem sSystem) {
        sSystemMapper.insert(sSystem);
        return findOne(sSystem.getId());
    }

    @Override
    public SSystem insertSelective(SSystem sSystem) {
        sSystemMapper.insertSelective(sSystem);
        return findOne(sSystem.getId());
    }

    @Override
    public SSystem updateById(SSystem sSystem) {
        sSystemMapper.updateByPrimaryKeySelective(sSystem);
        return findOne(sSystem.getId());
    }

    @Override
    public SSystem findOne(Long id) {
        return sSystemMapper.selectByPrimaryKey(id);
    }

    @Override
    public List<SSystem> findAll(Pageable pageable) {
        int pageNumber = pageable.getPageNumber();
        int pageSize = pageable.getPageSize();
        PageHelper.startPage(pageNumber, pageSize);
        return sSystemMapper.selectAll();
    }

    @Override
    public void deleteById(Long id) {
        sSystemMapper.deleteByPrimaryKey(id);
    }

    @Override
    public int deleteByHostSiteId(long hostId, long siteId) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        return sSystemMapper.deleteByExample(example);
    }

    @Override
    public List<SSystem> findSSystemByHostSiteId(Long hostId, Long siteId) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        example.setOrderByClause("`id` ASC");
        return sSystemMapper.selectByExample(example);
    }

    @Override
    public List<SSystem> findSSystemByHostSiteFormId(long hostId, long siteId, long formId) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        if (formId == -2) {
            criteria.andGreaterThan("formId", 0);
        } else if (formId >= 0) {
            criteria.andEqualTo("formId", formId);
        }
        example.setOrderByClause("`id` ASC");
        return sSystemMapper.selectByExample(example);
    }

    @Override
    public List<SSystem> findSSystemByHostSiteIdAndIds(long hostId, long siteId, List<Long> systemIds) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andIn("id", systemIds);
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        example.setOrderByClause("`id` ASC");
        return sSystemMapper.selectByExample(example);
    }

    @Override
    public SSystem findSSystemByIdHostSiteId(Long id, Long hostId, Long siteId) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", id);
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        example.setOrderByClause("`id` ASC");
        List<SSystem> selectByExample = sSystemMapper.selectByExample(example);
        if (CollUtil.isEmpty(selectByExample)) {
            return null;
        }
        return selectByExample.get(0);
    }

    /**
     * 删除步骤 一、删除系统分类 二、删除系统内容 三、删除系统 四、删除SEO带有系统的部分
     */
    @Override
    @Transactional
    public boolean deleteSystemBySSystem(SSystem sSystem) {
        if (sSystem.getSystemTypeId().longValue() == 1L) {
            // 带分类文章系统
            if (!sCategoriesServiceImpl.deleteBySystemId(sSystem.getId())) {
                String message = "通过系统ID删除分类数据失败！id: " + sSystem.getId();
                logger.error(message);
                throw new RuntimeException(message);
            }
            if (!cArticleServiceImpl.clearBySystem(sSystem)) {
                String message = "通过系统数据删除下载系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }
        } else if (sSystem.getSystemTypeId().longValue() == 2L) {
            // 无分类的文章系统
            if (!cArticleServiceImpl.clearBySystem(sSystem)) {
                String message = "通过系统数据删除下载系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }
        } else if (sSystem.getSystemTypeId().longValue() == 3L) {
            /**
             * 删除产品系统，首先删除产品系统的分类
             */
            if (!sCategoriesServiceImpl.deleteBySystemId(sSystem.getId())) {
                String message = "通过系统ID删除分类数据失败！id: " + sSystem.getId();
                logger.error(message);
                throw new RuntimeException(message);
            }
            // 删除产品系统中的数据
            boolean clearBySystem = cProductServiceImpl.clearBySystem(sSystem);
            if (!clearBySystem) {
                String message = "通过系统数据删除下载系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }

        } else if (sSystem.getSystemTypeId().longValue() == 4L) {
            String message = "目前还没有 不带分类产品系统，所以无法进行删除！";
            logger.error(message);
            throw new RuntimeException(message);
        } else if (sSystem.getSystemTypeId().longValue() == 5L) {
            /**
             * 删除下载系统，首先删除分类数据
             */
            if (!sCategoriesServiceImpl.deleteBySystemId(sSystem.getId())) {
                String message = "通过系统ID删除分类数据失败！id: " + sSystem.getId();
                logger.error(message);
                throw new RuntimeException(message);
            }
            // 删除下载系统中的数据
            boolean clearBySystem = cDownloadServiceImpl.clearBySystem(sSystem);
            if (!clearBySystem) {
                String message = "通过系统数据删除下载系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }
        } else if (sSystem.getSystemTypeId().longValue() == 6L) {
            /**
             * 删除FAQ系统，首先删除分类数据
             */
            if (!sCategoriesServiceImpl.deleteBySystemId(sSystem.getId())) {
                String message = "通过系统ID删除分类数据失败！id: " + sSystem.getId();
                logger.error(message);
                throw new RuntimeException(message);
            }
            // 删除FAQ系统中的数据
            boolean clearBySystem = cFaqServiceImpl.clearBySystem(sSystem);
            if (!clearBySystem) {
                String message = "通过系统数据删除下载系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }
        } else if (sSystem.getSystemTypeId().longValue() == 7L) {
            /**
             * 删除信息系统
             */
            boolean clearBySystem = cInformationServiceImpl.clearBySystem(sSystem);
            if (!clearBySystem) {
                String message = "通过系统数据删除信息系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }
        } else if (sSystem.getSystemTypeId().longValue() == 8L) {
            /**
             * 删除产品表格系统，首先删除产品表格系统的分类
             */
            if (!sCategoriesServiceImpl.deleteBySystemId(sSystem.getId())) {
                String message = "通过系统ID删除分类数据失败！id: " + sSystem.getId();
                logger.error(message);
                throw new RuntimeException(message);
            }
            // 删除产品表格系统中的数据
            boolean clearBySystem = cPdtableServiceImpl.clearBySystem(sSystem);
            if (!clearBySystem) {
                String message = "通过系统数据删除产品表格系统数据失败！sSystem: " + sSystem;
                logger.error(message);
                throw new RuntimeException(message);
            }
        }

        // 四、 删除 s_seo_item 数据
        boolean deleteBySystemId = sSeoItemServiceImpl.deleteBySystemId(sSystem.getId());
        if (!deleteBySystemId) {
            throw new RuntimeException("删除文章系统的 s_seo_item 数据失败！ sSystem: " + sSystem);
        }

        // 四、 删除 s_seo_category 数据
        deleteBySystemId = sSeoCategoryServiceImpl.deleteBySystemId(sSystem.getId());
        if (!deleteBySystemId) {
            throw new RuntimeException("删除文章系统的 s_seo_category 数据失败！ sSystem: " + sSystem);
        }

        sComponentQuoteSystemServiceImpl.deleteByHostSiteQuoteSystemId(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId());

        // 修改 s_page.system_id 改系统ID的数据为 0
        List<SPage> sPageList = sPageServiceImpl.findByHostSiteSystemId(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId());
        if (CollUtil.isNotEmpty(sPageList)) {
            for (SPage sPage : sPageList) {
                sPage.setSystemId(0L);
                sPageServiceImpl.updateById(sPage);
            }
        }

        // 删除对应的 s_system_custom_link 数据信息
        sSystemItemCustomLinkServiceImpl.deleteByHostSiteSystemId(sSystem.getHostId(), sSystem.getSiteId(), sSystem.getId());

        // 删除自己
        return sSystemMapper.delete(sSystem) > 0;
    }

    @Override
    public List<SSystem> findInfosBySystemTypeIds(long hostId, long siteId, List<Long> systemTypeIds) {
        if (CollectionUtils.isEmpty(systemTypeIds)) {
            return findSSystemByHostSiteId(hostId, siteId);
        }
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        criteria.andIn("systemTypeId", systemTypeIds);
        example.setOrderByClause("`id` ASC");
        return sSystemMapper.selectByExample(example);
    }

    @Override
    public int totalByHostId(long hostId) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        return sSystemMapper.selectCountByExample(example);
    }

    @Override
    public int totalByHostSiteId(long hostId, long siteId) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        return sSystemMapper.selectCountByExample(example);
    }

    @Override
    public PageInfo<SSystem> findPageInfoAll(long hostId, long siteId, int pageNum, int pageSize) {
        Example example = new Example(SSystem.class);
        Criteria criteria = example.createCriteria();
        criteria.andEqualTo("hostId", hostId);
        criteria.andEqualTo("siteId", siteId);
        PageHelper.startPage(pageNum, pageSize);
        List<SSystem> listSSystem = sSystemMapper.selectByExample(example);
        PageInfo<SSystem> result = new PageInfo<>(listSSystem);
        return result;
    }

    @Override
    public Integer querySystemTypeCount(int trial, int review, long systemTypeId) {
        return sSystemMapper.querySystemTypeCount(trial, review, systemTypeId);
    }

}
